package com.hst.capacity.domain.service.impl;

import com.hst.capacity.domain.common.constants.Constants;
import com.hst.capacity.domain.exception.BusinessException;
import com.hst.capacity.domain.model.entity.order.base.BaseOrderEntity;
import com.hst.capacity.domain.model.entity.order.express.ExpressOrderEntity;
import com.hst.capacity.domain.model.entity.order.job.ExpressTaskEntity;
import com.hst.capacity.domain.model.entity.order.job.IntercityTaskEntity;
import com.hst.capacity.domain.model.entity.order.job.JobPlatformEntity;
import com.hst.capacity.domain.model.entity.order.job.SpecialTaskEntity;
import com.hst.capacity.domain.model.entity.vehicle.VehicleTypeEntity;
import com.hst.capacity.domain.model.request.OrderParam;
import com.hst.capacity.domain.service.JobPlatformService;
import com.hst.capacity.infra.convertor.JobPlatformConvertor;
import com.hst.capacity.infra.persistence.jpa.order.express.ExOrderRepository;
import com.hst.capacity.infra.persistence.jpa.order.intercity.IcOrderRepository;
import com.hst.capacity.infra.persistence.jpa.order.job.ExpressTaskRepository;
import com.hst.capacity.infra.persistence.jpa.order.job.IntercityTaskRepository;
import com.hst.capacity.infra.persistence.jpa.order.job.JobPlatformRepository;
import com.hst.capacity.infra.persistence.jpa.order.job.SpecialTaskRepository;
import com.hst.capacity.infra.persistence.jpa.order.pool.OrderPoolRepository;
import com.hst.capacity.infra.persistence.jpa.order.specialcar.SpCarOrderRepository;
import com.hst.capacity.infra.persistence.jpa.vehicle.VehicleTypeRepository;
import com.hst.capacity.infra.util.DateUtil;
import com.hst.capacity.infra.util.NumUtil;
import com.hst.capacity.infra.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class JobPlatformServiceImpl implements JobPlatformService {

    @Autowired
    private JobPlatformRepository jobRepository;

    @Autowired
    private ExOrderRepository exOrderRepository;

    @Autowired
    private SpCarOrderRepository specialCarOrderRepository;

    @Autowired
    private OrderPoolRepository orderPoolRepository;

    @Autowired
    private IcOrderRepository icOrderRepository;

    @Autowired
    private VehicleTypeRepository vehicleTypeRepository;

    @Autowired
    private ExpressTaskRepository expressTaskRepository;

    @Autowired
    private IntercityTaskRepository intercityTaskRepository;

    @Autowired
    private SpecialTaskRepository specialTaskRepository;

    /**
     * 创建新任务
     * @param order
     * @param param
     * @return
     */
    @Override
    public JobPlatformEntity assignOrderToJob(BaseOrderEntity order, OrderParam param) {
        JobPlatformEntity task = jobRepository.findByIdDriver(param.getIdDriver());
        if ( task !=null && Constants.TaskStatus.DISPATCH_COMPLETE == task.getStatus()) {
            throw new BusinessException(5002, "当前司机派单已经完成，请指派其他司机");
            //return task;
        }

        VehicleTypeEntity vtDriver = vehicleTypeRepository.findByIdDriver(param.getIdDriver());
        //包车check车型是否匹配
        if (Constants.OrderCarpoolType.Chartered == order.getCarpoolType()){
            //用车类型不匹配
            if (param.getModuleType() == Constants.OrderModuleType.SPECIAL) {
                if (vtDriver.getIdVehicleType() != order.getIdVehicleType()) {
                    throw new BusinessException(5002, "乘客指定车型不一致，不能派单");
                }
            } else {
                VehicleTypeEntity vtOrder = vehicleTypeRepository.findByIdVehicleType(order.getIdVehicleType());
                if (vtDriver.getSeats() < vtOrder.getSeats()) {
                    throw new BusinessException(5002, "所派司机车型座位不能满足乘客人数");
                }
            }
        }

        // 没有司机任务时，创建新任务
        if (task == null) {
            // 创建新任务
            task = newJob(order, param);

        } else {
            // 有司机任务时，检索任务中执行的订单数
            //int taskOrderCnt = findCountByIdTask(task);
            int passengersInCarNumber = task.getPassengersIncarNumber();
            // 任务中执行的订单数是0时
            if (passengersInCarNumber <= 0) {
                // 无执行中订单时，删除任务
                delJob(task);
                // 创建新任务
                task = newJob(order, param);
            }

            // 任务中执行的订单数大于0时
            if (passengersInCarNumber > 0) {
                // 业务类型校验(城际，专车，快车)
                if (param.getModuleType() != task.getModuleType()) {
                    throw new BusinessException(5002, "有其他业务订单未完成，无法接实时订单");
                }
                // 当前任务是包车订单时，不能派单
                if (Constants.OrderCarpoolType.Chartered == task.getCarpoolType() ||
                        Constants.OrderCarpoolType.Chartered == order.getCarpoolType()) {
                    throw new BusinessException(5002,"已有订单，请指派其他司机");
                }
                // 在乘人数(已在车上人数+将要乘车人数，以下车人数不在内）+ 当前派单的订单人数
                passengersInCarNumber = task.getPassengersIncarNumber() + order.getPassengerNumber();
                // 在乘人数超过任务最多可乘坐人数
                if (passengersInCarNumber > (task.getSeating() - 1)) {
                    throw new BusinessException(5002,"乘客数超出最大人数，不能派单");
                }

                //更新任务信息(派单完成)
                updateJob(task, order);
            }
        }

        return task;
    }

    /**
     * 创建新任务
     * @param order
     * @param param
     * @return
     */
    @Override
    public JobPlatformEntity newJob(BaseOrderEntity order, OrderParam param){

        VehicleTypeEntity vt = vehicleTypeRepository.findByIdDriver(param.getIdDriver());
        if (vt == null)
            throw new BusinessException(5002, "司机没有绑定车辆，请确认。");

        // 在乘人数超过任务最多可乘坐人数
        if (order.getPassengerNumber() > (vt.getSeats()-1))
            throw new BusinessException(5002,"乘客数超出最大人数，不能派单");

        JobPlatformEntity task = new JobPlatformEntity();
        task.setIdTask(StringUtil.generateUuid());
        task.setModuleType(param.getModuleType());
        task.setIdDriver(param.getIdDriver());
        if (Constants.OrderModuleType.EXPRESS == param.getModuleType()) {
            task.setRegionCode(((ExpressOrderEntity) order).getRegionCode());
        }
        task.setIdLine(order.getIdLine());
        task.setIdSchedule("");
        task.setScheduleTime(DateUtil.getNowTime());
        task.setIdFranchisee(order.getIdFranchisee());
        task.setIdShareRoute("");
        task.setQueueNum(0);
        task.setSeating(vt.getSeats());
        task.setPassengersNumber(0);
        task.setPassengersIncarNumber(order.getPassengerNumber());
        task.setTransportedPassengersNumber(0);
        task.setTaskSumMoney(NumUtil.getFloat(order.getEstimatedMoney()));
        task.setTaskAdditionalMoney(NumUtil.getFloat(order.getAdditionalMoney()));
        task.setTaskCouponMoney(NumUtil.getFloat(order.getCouponDiscount()));
        // carpool_type 0:拼车，1:包车
        task.setCarpoolType(order.getCarpoolType());
        // 派单中
        if (order.getCarpoolType() == Constants.OrderCarpoolType.Chartered)
            task.setStatus(Constants.TaskStatus.DISPATCH_COMPLETE);
        else
            task.setStatus(Constants.TaskStatus.COLLAGE);
        task.setTaskSubsidy(0F);
        task.setTaskNoLoadSubsidy(0F);

        task = jobRepository.saveAndFlush(task);

        return task;
    }

    /**
     * 更新任务
     * @param task
     * @param order
     * @return
     */
    @Override
    public void updateJob(JobPlatformEntity task,BaseOrderEntity order){
        // 在乘人数(已在车上人数+将要乘车人数，以下车人数不在内）+ 当前派单的订单人数
        Integer passengersInCarNumber = task.getPassengersIncarNumber() + order.getPassengerNumber();
        // 在乘人数超过任务最多可乘坐人数
        if (passengersInCarNumber > (task.getSeating()-1))
            throw new BusinessException(5002,"乘客数超出最大人数，不能派单");

        // 预估金额
        Float taskSumMoney = NumUtil.getFloat(task.getTaskSumMoney()) + NumUtil.getFloat(order.getEstimatedMoney());
        // 任务额外金额
        Float taskAdditionalMoney = NumUtil.getFloat(task.getTaskAdditionalMoney()) + NumUtil.getFloat(order.getAdditionalMoney());
        // 任务优惠金额
        Float taskCouponMoney = NumUtil.getFloat(task.getTaskCouponMoney()) + NumUtil.getFloat(order.getCouponDiscount());

        // 派单中
        if (order.getCarpoolType() == Constants.OrderCarpoolType.Chartered
                || passengersInCarNumber == (task.getSeating()-1)) {
            task.setStatus(Constants.TaskStatus.DISPATCH_COMPLETE);
        } else {
            task.setStatus(Constants.TaskStatus.COLLAGE);
        }
        task.setPassengersIncarNumber(passengersInCarNumber);
        task.setScheduleTime(DateUtil.getNowTime());
        task.setTaskSumMoney(taskSumMoney);
        task.setTaskAdditionalMoney(taskAdditionalMoney);
        task.setTaskCouponMoney(taskCouponMoney);

        jobRepository.saveAndFlush(task);
    }

    /**
     * 删除任务
     * @param task
     * @return
     */
    @Override
    public void delJob(JobPlatformEntity task){
        // 已运送乘客数大于0时，任务移动到历史表
        if (task.getTransportedPassengersNumber() > 0) {
            // 已完成订单移动到历史表
            switch (task.getModuleType()) {
                case Constants.OrderModuleType.SPECIAL:
                    SpecialTaskEntity spTask= JobPlatformConvertor.INSTANCE.convertJobPlatformSpEntity(task);
                    specialTaskRepository.save(spTask);
                    break;
                case Constants.OrderModuleType.INTERCITY:
                    IntercityTaskEntity icTask= JobPlatformConvertor.INSTANCE.convertJobPlatformIcEntity(task);
                    intercityTaskRepository.save(icTask);
                    break;
                case Constants.OrderModuleType.EXPRESS:
                    ExpressTaskEntity exTask= JobPlatformConvertor.INSTANCE.convertJobPlatformExEntity(task);
                    expressTaskRepository.save(exTask);
                    break;
            }
        }
        jobRepository.delete(task);
    }

}
